#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "renlian.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
    ui->setupUi(this);
    ReadSerial();                 // 读取可用串口并更新到下拉列表

    // 创建串口对象（堆上分配内存，需在析构函数中释放）
    serial = new QSerialPort;

    // 连接串口的readyRead信号到数据读取槽函数
    // 当串口有数据可读时，自动触发ReadData()函数
     QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReadData);

    this->moduleMTCount = 0;      // 初始化温湿度数据点计数器
    this->status = 0;             // 初始状态设为温度传感器页面（0：温湿度，1：人体红外，2：火焰）
    DrawDynamicPlot();            // 绘制温湿度动态图表
    QStringList strList;
    strList<<"9600"<<"14400"<<"19200"<<"38400"<<"56000"<<"57600"<<"115200"<<"128000";
    ui->comboBox_2->addItems(strList);
    QStringList strList_1;
    strList_1<<"5"<<"6"<<"7"<<"8";
    ui->comboBox_3->addItems(strList_1);
    QStringList strList_2;
    strList_2<<"NONE"<<"ODD"<<"EVEN"<<"MARY"<<"SPACE";
    ui->comboBox_4->addItems(strList_2);
    database = new sqldatabase("all.db");
    //创建表格设置ID为主键自动增加
    QString str="create table IF NOT EXISTS wendu_shidu(\
            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\
            wendu varchar(255),\
            shidu varchar(255)\
       )";
    database->execSql(str);
    this->mount=0;
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::ReadSerial(){

    //获取可用串口名到下拉栏
    QList<QSerialPortInfo> list = QSerialPortInfo::availablePorts();
    if(ui->comboBox_1->count()!=list.count())
        ui->comboBox_1->clear();
    for(int i=0; i<list.size(); i++)
    {
        ui->comboBox_1->addItem(list.at(i).portName());
    }
}

void MainWindow::ReadData()//读取接收到的信息
{

    QByteArray buf = serial->readAll();

    if (buf.isEmpty()) {
        qDebug() << "串口接收数据为空";
        return;
    }

    // 校验数据长度（至少需要11字节）
    if (buf.size() < 11) {
        qDebug() << "数据长度不足，至少需要11字节，实际" << buf.size();
        return;
    }

    // 解析标签（第1字节）
    int tag = static_cast<quint8>(buf[0]);

    // 解析数据部分（从第2字节开始）
    QByteArray dataPart = buf.mid(1, buf.size() - 2); // 排除标签和校验和

    // 转换数据部分为十六进制字符串
    QString hexStr = dataPart.toHex(' ').toUpper();
    QStringList hexParts = hexStr.split(' ', Qt::SkipEmptyParts);

    // 打印调试信息
    qDebug() << "接收到数据 (Hex):" << buf.toHex(' ').toUpper();
    qDebug() << "标签:" << QString::number(tag, 16);
    qDebug() << "数据部分:" << hexStr;

    // 根据标签处理数据
    switch (tag) {
    //人体红外（假设标签为0x10）
    case 0x10: {
        if(this->status != 1) return;
        if (hexParts.size() >= 9) {
            QString sensorValue = hexParts[8]; // 第9个字节

            ui->textBrowser->append("Tag: 10");
            ui->textBrowser->append("人体红外数据位: " + sensorValue);

            if(sensorValue == "30"){
                sliceWu->setValue(100);
                sliceYou->setValue(0);
            } else {
                sliceWu->setValue(0);
                sliceYou->setValue(100);
            }
        }
        break;
    }

    //温湿度（假设标签为0x20）
    case 0x20: {
        if(this->status != 0) return;
        if (hexParts.size() >= 10) {
            bool ok1, ok2;
            this->temperature = hexParts[8].toInt(&ok1, 16); // 第9个字节
            this->moist = hexParts[9].toInt(&ok2, 16);       // 第10个字节
                qint32 tm = this->temperature;
                qint32 mo = this->moist;
                QString str = QString("insert into wendu_shidu(wendu,shidu) values('%1','%2')").arg(tm).arg(mo);
                if(NULL != database->execSql(str))
                {
                    qDebug()<<"写入成功";
                }
            if (ok1 && ok2) {
                ui->textBrowser->append("Tag: 20");
                ui->textBrowser->append(QString("温度和湿度: %1 %2 %3")
                                            .arg(this->temperature).arg(this->moist).arg(this->moduleMTCount));
                this->mount++;
                qDebug()<<"mount:"<<this->mount;
                temperatureSeries->append(this->moduleMTCount, this->temperature);
                moistSeries->append(this->moduleMTCount++, this->moist);
                UpdateChartRangeMT();
                this->ui->chartView->update();
            } else {
                qDebug() << "温湿度数据转换失败";
            }
        }
        break;
    }

    //火焰（假设标签为0x30）
    case 0x30: {
        // qDebug()<<"22222222222222222222222222";
        if(this->status != 2) return;
        // qDebug()<<"111111111111111111";
        if (hexParts.size() >= 9) {
            QString sensorValue = hexParts[8]; // 第9个字节

            ui->textBrowser->append("Tag: 30");
            ui->textBrowser->append("火焰传感器数据位: " + sensorValue);

            if(sensorValue == "31"){
                ColseFan(); // 修正拼写错误
                sliceWuFire->setValue(100);
                sliceYouFire->setValue(0);
            } else {
                OpenFan();
                sliceWuFire->setValue(0);
                sliceYouFire->setValue(100);
            }
        }
        break;
    }

    // // 处理0x1E标签（示例数据中的标签）
    // case 0x1E: {
    //     if(this->status != 0) return; // 假设0x1E对应温湿度
    //     if (hexParts.size() >= 9) {
    //         bool ok1, ok2;
    //         // 提取温度和湿度数据（根据实际协议调整索引）
    //         this->temperature = hexParts[7].toInt(&ok1, 16); // 示例数据中的第8个字节
    //         this->moist = hexParts[8].toInt(&ok2, 16);       // 示例数据中的第9个字节
    //         // qDebug()<<"2344645767869679789tyu545445t";

    //         if (ok1 && ok2) {
    //             ui->textBrowser->append("Tag: 30 (0x1E)"); // 显示实际标签值
    //             ui->textBrowser->append(QString("温度和湿度: %1 %2 %3")
    //                                         .arg(this->temperature).arg(this->moist).arg(this->moduleMTCount));

    //             temperatureSeries->append(this->moduleMTCount, this->temperature);
    //             moistSeries->append(this->moduleMTCount++, this->moist);
    //             UpdateChartRangeMT();
    //             this->ui->chartView->update();
    //         } else {
    //             qDebug() << "温湿度数据转换失败";
    //         }
    //     }
    //     break;
    // }

    default:
        qDebug() << "未知标签: 0x" << QString::number(tag, 16);
        break;
    }
}

void MainWindow::on_pushButton_4_clicked()
{
    if(ui->pushButton_4->text() == "打开串口")
    {
        ui->comboBox_1->setEnabled(false);
        serialStatus = false;
        this->ui->pushButton_4->setText("关闭串口");
        //设置串口为下拉栏所选串口名
        serial->setPortName(ui->comboBox_1->currentText());
        QString baudRateStr = ui->comboBox_2->currentText();  // 获取波特率文本
        qint32 baudRate = baudRateStr.toInt();                // 转为整数
        //设置波特率
        serial->setBaudRate(baudRate);
        //设置数据位数
        // 获取数据位文本并映射到枚举值
        QString dataBitsStr = ui->comboBox_3->currentText();  // 假设使用 comboBox_dataBits
        QSerialPort::DataBits dataBits = QSerialPort::Data8;  // 默认值
        if (dataBitsStr == "5") {
            dataBits = QSerialPort::Data5;
        } else if (dataBitsStr == "6") {
            dataBits = QSerialPort::Data6;
        } else if (dataBitsStr == "7") {
            dataBits = QSerialPort::Data7;
        } else if (dataBitsStr == "8") {
            dataBits = QSerialPort::Data8;
        } else {
            qWarning() << "不支持的数据位: " << dataBitsStr;
        }
        serial->setDataBits(dataBits);  // 设置数据位
        //设置校验位
        QString parityStr = ui->comboBox_4->currentText();  // 奇偶校验下拉框（需在UI中添加，命名为 comboBox_parity）
        QSerialPort::Parity parity = QSerialPort::NoParity;       // 默认无校验

        // 映射字符串到奇偶校验枚举值
        if (parityStr == "NONE") {
            parity = QSerialPort::NoParity;
        } else if (parityStr == "ODD") {
            parity = QSerialPort::OddParity;
        } else if (parityStr == "EVEN") {
            parity = QSerialPort::EvenParity;
        } else if (parityStr == "MARY") {
            parity = QSerialPort::MarkParity;
        } else if (parityStr == "SPACE") {
            parity = QSerialPort::SpaceParity;
        } else {
            qWarning() << "不支持的校验位: " << parityStr;
            return; // 无效校验位时提前返回
        }

        serial->setParity(parity);  // 设置奇偶校验位
        //设置停止位
        serial->setStopBits(QSerialPort::OneStop);
        //设置流控制
        serial->setFlowControl(QSerialPort::NoFlowControl);
        //打开串口 同时判断是否成功
        bool info = serial->open(QIODevice::ReadWrite);
        if(info == true)
        {
            qDebug()<<"success";
            //改变label颜色（指示灯)
            //关闭下拉栏设置使能
            //改变按钮文本为"关闭串口"
        }
        else
        {
            qDebug()<<"fail";
        }
    }
    else
    {
        ui->comboBox_1->setEnabled(true);
        serialStatus = true;
        this->ui->pushButton_4->setText("打开串口");
        serial->close();
        //关闭串口
        //改变label颜色（指示灯)
        //恢复下拉栏设置使能
        //改变按钮文本为"打开串口"
    }

}
void MainWindow::DrawDynamicPlot(){
    chartMT = new QChart;
    temperatureSeries = new QLineSeries;
    temperatureSeries->setName(u8"温度");
    temperatureSeries->setColor(Qt::red); // 设置温度曲线为红色，便于区分

    moistSeries = new QSplineSeries;
    moistSeries->setName(u8"湿度");
    moistSeries->setColor(Qt::blue); // 设置湿度曲线为蓝色，便于区分

    // 创建坐标轴
    QValueAxis *axisX = new QValueAxis();
    QValueAxis *axisYTemp = new QValueAxis(); // 温度专用Y轴
    QValueAxis *axisYMoist = new QValueAxis(); // 湿度专用Y轴

    // 设置X轴范围（采样点数量）
    axisX->setRange(0, 30);
    axisX->setTitleText("采样点");

    // 设置温度Y轴范围（根据实际数据调整）
    axisYTemp->setRange(0, 50);
    axisYTemp->setTitleText("温度 (°C)");
    axisYTemp->setLabelFormat("%.1f"); // 设置小数位数
    axisYTemp->setGridLineVisible(true);

    // 设置湿度Y轴范围（湿度通常为0-100%）
    axisYMoist->setRange(0, 100);
    axisYMoist->setTitleText("湿度 (%)");
    axisYMoist->setLabelFormat("%.0f"); // 整数显示
    axisYMoist->setGridLineVisible(false); // 避免网格线重叠

    // 将坐标轴添加到图表
    chartMT->addAxis(axisX, Qt::AlignBottom);
    chartMT->addAxis(axisYTemp, Qt::AlignLeft);   // 温度轴在左侧
    chartMT->addAxis(axisYMoist, Qt::AlignRight); // 湿度轴在右侧

    // 添加序列到图表
    chartMT->addSeries(temperatureSeries);
    chartMT->addSeries(moistSeries);

    // 将序列绑定到对应坐标轴
    temperatureSeries->attachAxis(axisX);
    temperatureSeries->attachAxis(axisYTemp);

    moistSeries->attachAxis(axisX);
    moistSeries->attachAxis(axisYMoist);

    // 设置图表标题
    chartMT->setTitle(u8"温湿度实时监测");
    chartMT->legend()->setVisible(true);
    chartMT->legend()->setAlignment(Qt::AlignBottom);

    // 设置画布
    this->ui->chartView->setChart(chartMT);
    this->ui->chartView->setRenderHint(QPainter::Antialiasing);


}


void MainWindow::on_pushButton_2_clicked()
{
    //火焰
    this->status = 2;
    ui->groupBox->setTitle("火焰传感");

    chartUV = new QChart;
    // 获取图例对象
    QLegend *legend = chartUV->legend();
    // 设置字体大小
    QFont font = legend->font();
    font.setPointSize(10);  // 调整字体大小（影响图例文字和图标）
    legend->setFont(font);
    //创建饼状图序列
    QPieSeries *pieSeries = new QPieSeries;

    //设置饼状图数据
    sliceYouFire = pieSeries->append("无火",100);
    sliceYouFire->setBrush(QColor(0, 255, 0));  // 填充绿色
    sliceYouFire->setLabelVisible(false);


    sliceWuFire = pieSeries->append("有火",0);
    sliceWuFire->setLabelVisible(false);
    sliceWuFire->setBrush(QColor(255, 0, 0));  // 填充红色

    QPieSlice *slice = pieSeries->slices().at(0);
    slice->setExploded(true);//设置exploded动画效果



    //将饼状图加入图表
    this->chartUV->addSeries(pieSeries);

    //将图表加入画布

    ui->chartView->setChart(this->chartUV);
    ui->chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿
    ui->chartView->update();
}


void MainWindow::on_pushButton_clicked()
{
    //温湿度
    this->status = 0;
    DrawDynamicPlot();
}
void MainWindow::UpdateChartRangeMT(){
    QValueAxis *axisX = qobject_cast<QValueAxis*>(chartMT->axisX());
    if(this->moduleMTCount>15)
        axisX->setRange(0, 30+this->moduleMTCount);

}
void MainWindow::OpenFan(){
    QString data = "31";
    // qDebug()<<"11111111123213213";
    serial->write(QByteArray::fromHex("21 01 09 01 5A 40 2C 66 23 31 1B"));

}

void MainWindow::ColseFan(){
    QString data = "30";

    serial->write(QByteArray::fromHex(QString("21 01 09 01 5A 40 2C 66 23 %1 1B").arg(data).toLatin1()));

}

void MainWindow::Openfan_1()
{
    ui->comboBox_1->setEnabled(false);
    // qDebug()<<ui->comboBox_1->currentText()<<"21321ewqrwdqwdf";
    serialStatus = false;
    // this->ui->pushButton->setText("关闭串口");
    //设置串口为下拉栏所选串口名
    serial->setPortName("COM6");
    //设置波特率
    serial->setBaudRate(QSerialPort::Baud115200);
    //设置数据位数
    serial->setDataBits(QSerialPort::Data8);
    //设置校验位
    serial->setParity(QSerialPort::NoParity);
    //设置停止位
    serial->setStopBits(QSerialPort::OneStop);
    //设置流控制
    serial->setFlowControl(QSerialPort::NoFlowControl);
    //打开串口 同时判断是否成功
    bool info = serial->open(QIODevice::ReadWrite);
    OpenFan();
    serial->close();
    if(info == true)
    {
        qDebug()<<"success";
        //改变label颜色（指示灯)
        //关闭下拉栏设置使能
        //改变按钮文本为"关闭串口"
    }
    else
    {
        qDebug()<<"fail";
    }

}
// void MainWindow::Openfan_1()
// {
//     ui->comboBox_1->setEnabled(false);
//     qDebug()<<ui->comboBox_1->currentText()<<"21321ewqrwdqwdf";
//     serialStatus = false;
//     // this->ui->pushButton->setText("关闭串口");
//     //设置串口为下拉栏所选串口名
//     serial->setPortName("COM6");
//     //设置波特率
//     serial->setBaudRate(QSerialPort::Baud115200);
//     //设置数据位数
//     serial->setDataBits(QSerialPort::Data8);
//     //设置校验位
//     serial->setParity(QSerialPort::NoParity);
//     //设置停止位
//     serial->setStopBits(QSerialPort::OneStop);
//     //设置流控制
//     serial->setFlowControl(QSerialPort::NoFlowControl);
//     //打开串口 同时判断是否成功
//     bool info = serial->open(QIODevice::ReadWrite);
//     serial->write(QByteArray::fromHex("21 01 09 01 5A 40 2C 66 23 31 1B"));
//     serial->close();
//     if(info == true)
//     {
//         qDebug()<<"success";
//         //改变label颜色（指示灯)
//         //关闭下拉栏设置使能
//         //改变按钮文本为"关闭串口"
//     }
//     else
//     {
//         qDebug()<<"fail";
//     }

// }
void MainWindow::on_pushButton_3_clicked()
{
    QString data = "";
    if(this->ui->pushButton_3->text()=="打开风扇"){
        data = "31";
        this->ui->pushButton_3->setText("关闭风扇");
    }
    else{
        data = "30";
        this->ui->pushButton_3->setText("打开风扇");
    }

    serial->write(QByteArray::fromHex(QString("21 01 09 01 5A 40 2C 66 23 %1 1B").arg(data).toLatin1()));

}


void MainWindow::on_pushButton_5_clicked()
{
    // QSqlQuery query; // 假设database有获取QSqlDatabase的方法
    QString str = "SELECT wendu, shidu FROM wendu_shidu ORDER BY id DESC LIMIT 30";
    database->execSql(str);
    if (database->query) {
        QList<QPair<int, int>> dataPoints; // 存储温湿度数据对

        while (database->query->next()) {
            int temperature = database->query->value(0).toInt();
            int humidity = database->query->value(1).toInt();
            dataPoints.append(qMakePair(temperature, humidity));

            qDebug() << "读取数据:" << temperature << "°C," << humidity << "%";
        }

        qDebug() << "成功读取" << dataPoints.size() << "条数据";
        // 创建图表
        chartMT = new QChart;
        temperatureSeries = new QLineSeries;
        temperatureSeries->setName(u8"温度");
        temperatureSeries->setColor(Qt::red); // 设置温度曲线为红色

        moistSeries = new QSplineSeries;
        moistSeries->setName(u8"湿度");
        moistSeries->setColor(Qt::blue); // 设置湿度曲线为蓝色

        // 创建坐标轴
        QValueAxis *axisX = new QValueAxis();
        QValueAxis *axisYTemp = new QValueAxis(); // 温度专用Y轴
        QValueAxis *axisYMoist = new QValueAxis(); // 湿度专用Y轴

        // 设置X轴范围（采样点数量）
        axisX->setRange(0, qMax(30, dataPoints.size())); // 根据数据量调整X轴范围
        axisX->setTitleText("采样点");

        // 自动计算温度Y轴范围
        int minTemp = INT_MAX, maxTemp = INT_MIN;
        int minMoist = INT_MAX, maxMoist = INT_MIN;

        for (const auto& point : dataPoints) {
            minTemp = qMin(minTemp, point.first);
            maxTemp = qMax(maxTemp, point.first);
            minMoist = qMin(minMoist, point.second);
            maxMoist = qMax(maxMoist, point.second);
        }

        // 设置温度Y轴范围（留出一些余量）
        axisYTemp->setRange(qMax(0, minTemp - 5), qMin(50, maxTemp + 5));
        axisYTemp->setTitleText("温度 (°C)");
        axisYTemp->setLabelFormat("%.1f");
        axisYTemp->setGridLineVisible(true);

        // 设置湿度Y轴范围（湿度通常为0-100%）
        axisYMoist->setRange(0, 100);
        axisYMoist->setTitleText("湿度 (%)");
        axisYMoist->setLabelFormat("%.0f");
        axisYMoist->setGridLineVisible(false);

        // 将坐标轴添加到图表
        chartMT->addAxis(axisX, Qt::AlignBottom);
        chartMT->addAxis(axisYTemp, Qt::AlignLeft);   // 温度轴在左侧
        chartMT->addAxis(axisYMoist, Qt::AlignRight); // 湿度轴在右侧

        // 添加序列到图表
        chartMT->addSeries(temperatureSeries);
        chartMT->addSeries(moistSeries);

        // 将序列绑定到对应坐标轴
        temperatureSeries->attachAxis(axisX);
        temperatureSeries->attachAxis(axisYTemp);

        moistSeries->attachAxis(axisX);
        moistSeries->attachAxis(axisYMoist);

        // 设置图表标题
        chartMT->setTitle(u8"温湿度实时监测");
        chartMT->legend()->setVisible(true);
        chartMT->legend()->setAlignment(Qt::AlignBottom);

        // 将数据添加到序列
        for (int i = 0; i < dataPoints.size(); ++i) {
            temperatureSeries->append(i, dataPoints[i].first);
            moistSeries->append(i, dataPoints[i].second);
        }

        // 设置画布
        this->ui->chartView->setChart(chartMT);
        this->ui->chartView->setRenderHint(QPainter::Antialiasing);

    } else {
        qDebug() << "查询执行失败:" << database->query->lastError().text();
    }
}


void MainWindow::on_pushButton_6_clicked()
{
    renlian *p = new renlian; // 传递 this 作为父窗口
    p->show();
    p->raise();
    p->activateWindow();

    // qDebug()<<"122weqwdq3e21eqe3e32f32fr";
    // serial->write(QByteArray::fromHex("21 01 09 01 5A 40 2C 66 23 31 1B"));
}

